package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"

	jsoniter "github.com/json-iterator/go"
)

type BookMap struct {
	Books []BookItem `json:"BookItem"`
}

type BookItem struct {
	Title     string
	Author    string   `json:"author"`
	Publisher string   `json:"publisher,omitempty"`
	Price     float32  `json:"pri"`
	Igonre    int32    `json:"-"`
	CTime     JsonTime `json:"ctime"`
}

type OmitEmpty struct {
	Map map[int]int `json:"Map,omitempty"`
}

type WithoutOmitEmpty struct {
	Map map[int]int `json:"Map"`
}

func main() {
	fmt.Println("json")
	{
		strBookJson, err := ioutil.ReadFile("book.json")
		if err != nil {
			log.Fatalln(err)
		}

		var stBookMap BookMap
		if err := json.Unmarshal(strBookJson, &stBookMap); err != nil {
			log.Fatalln(err)
		}
		stBookMap.Books[0].Publisher = "" // omitempty
		fmt.Println(stBookMap)

		for _, val := range stBookMap.Books {
			strBook, err := json.Marshal(val)
			if err != nil {
				log.Fatalln(err)
			}
			fmt.Println(val)
			fmt.Println(string(strBook))
		}
	}
	fmt.Println()
	{
		fmt.Println("jsoniter")
		strBookJson, err := ioutil.ReadFile("book.json")
		if err != nil {
			log.Fatalln(err)
		}

		var stBookMap BookMap
		if err := jsoniter.Unmarshal(strBookJson, &stBookMap); err != nil {
			log.Fatalln(err)
		}
		stBookMap.Books[0].Publisher = "" // omitempty
		fmt.Println(stBookMap)

		for _, val := range stBookMap.Books {
			strBook, err := jsoniter.Marshal(val)
			if err != nil {
				log.Fatalln(err)
			}
			fmt.Println(val)
			fmt.Println(string(strBook))
		}
	}

	fmt.Println("-------OmitEmpty-------")
	{
		fmt.Println("Case1:")
		st := &OmitEmpty{}
		b, _ := json.Marshal(st)
		fmt.Println(string(b))
		st2 := &OmitEmpty{}
		json.Unmarshal(b, st2)
		//st2.Map[1] = 1 // will panic here
	}
	{
		fmt.Println("Case2:")
		st := &OmitEmpty{}
		st.Map = make(map[int]int) // Add make
		b, _ := json.Marshal(st)
		fmt.Println(string(b))
		st2 := &OmitEmpty{}
		json.Unmarshal(b, st2)
		//st2.Map[1] = 1 // will panic here
	}
	{
		fmt.Println("Case3:")
		st := &WithoutOmitEmpty{}
		b, _ := json.Marshal(st)
		fmt.Println(string(b))
		st2 := &OmitEmpty{}
		json.Unmarshal(b, st2)
		//st2.Map[1] = 1 // will panic here
	}
	{
		fmt.Println("Case4:")
		st := &WithoutOmitEmpty{}
		st.Map = make(map[int]int) // Add make
		b, _ := json.Marshal(st)
		fmt.Println(string(b))
		st2 := &WithoutOmitEmpty{}
		json.Unmarshal(b, st2)
		st2.Map[1] = 1
	}
}
